<?php

class usuario_usuarioModel extends Model{
    protected $tabela = "usuario";
    protected $pkey   = "cod_usuario";
    private   $cookie = "usuario";
    protected $dados = array(
        'cod_usuario' => array(
            'name'    => "Código do usuário",
            'pkey'    => true,
            'ai'      => true,
            'type'    => 'int',
            'display' => true,
            'size'    => '11',
            'grid'    => true,
            'private' => true,
            'notnull' => true
         ),
 
        'email' => array(
            'name'     => 'Email',
            'type'     => 'varchar',
            'display'  => true,
            'unique'   => array('model' => 'usuario/usuario'),
            'size'     => '64',
            'notnull'  => true,
            'grid'     => true,
            'especial' => 'email',
            'description' => "O email será utilizado para fazer login e se comunicar com o site.",
         ),
        
        'user_name' => array(
            'name'     => 'Nome',
            'type'     => 'varchar',
            'display'  => true,
            'size'     => '64',
            'notnull'  => true,
            'grid'     => true,
            'description' => "Digite o seu nome completo",
         ),
        
        'user_cargo' => array(
            'name'        => 'Cargo',
            'type'        => 'varchar',
            'display'     => true,
            'size'        => '64',
            'notnull'     => true,
            'grid'        => true,
            'description' => "Digite o papel exercido na empresa por você",
         ),
        
        'senha' => array(
            'name'      => 'Senha',
            'type'      => 'varchar',
            'especial'  => 'senha',
            'size'      => '64',
            'notnull'   => true,
            'confirm'   => true,
            'private'   => true,
            'description' => "Digite uma senha contendo pelo menos 6 caracteres",
         ),
        
        'permissao' => array(
            'name'     => 'Tipo de Usuário',
            'type'     => 'enum',
            'default'  => 'Visitante',
            'options'  => array(
                'Webmaster' => 'Webmaster',
                'Admin'     => 'Admin',
                'Visitante' => 'Visitante'
            ),
            'size'     => '50',
            'grid'     => true,
            'notnull'  => true,
            'description' => "O tipo de usuário define o acesso do usuário no sistema. <br/>
                <b>Usuários do tipo visitante</b> podem acessar as áreas em que o login é necessário. <br/>
                <b>Usuários do tipo Admin</b> podem modificar dados de configuração do site e podem acessar
                qualquer área e visualizar todos os dados, portanto cuidado ao atribuir alguém como admin",
       	 ),
/*         
        'online' => array(
            'name'     => 'Usuário Online',
            'type'     => 'char',
            'default'  => '0',
            'size'     => '1',
            'notnull'  => true
       	 ),
        
        'user_criadoem' => array(
	    'name'     => 'Data de Criação',
	    'type'     => 'timestamp',
	    'notnull' => true,
	    'grid'    => true,
	    'display' => true,
            'default' => "CURRENT_TIMESTAMP",
            'especial' => 'hide'
        ),

        'perfil' => array(
            'name'     => 'Perfil de Usuário',
            'type' 	=> 'int',
            'fkey'      => array(
                'model' 	=> 'usuario/perfil',
                'keys'          => array('cod_perfil', 'per_nome'),
                'cardinalidade' => '1n'//nn 1n 11
            ),
            'grid'     => true,
            'notnull'  => true
       	 ),*/
        
        'confirmkey' => array(
            'type'     => 'varchar',
            'especial' => 'hide',
            'size'     => '64',
            'private'  => true
       	 )
    );
    
    public function getDados() {
        $var = parent::getDados();
        if(!$this->UserIsAdmin()){
            $var['permissao']['value']    = "Visitante";
            $var['permissao']['especial'] = 'hidden';
            $var['permissao']['type']     = 'varchar';
        }elseif(!$this->UserIsWebmaster()){
            unset($var['permissao']['options']['Webmaster']);
        }
        return $var;
    }

    //verifica se o usuario está logado
    public function IsLoged(){
        return (cookie::cookieExists($this->cookie));
    }//c

    //desloga o usuario
    public function Logout(){
        cookie::destroy($this->cookie);
        return true;
    }//c

    public function getCodUsuario(){
        $var = cookie::getVar($this->cookie);
        if($var != "") return $var['cod_usuario'];
        else           return 0;
    }//c
    
    public function getUserNick($user){
        if(!array_key_exists('user_name', $user)) return $user['email'];
        return $user['user_name']." (".$user['user_cargo'].")";
    }//c

    /*faz o login do usuario*/
    public function Login($login, $senha, $enc = true){

        //procura no banco de dados
        $login = str_replace(array("'", '"'), "", $login);
        $senha = str_replace(array("'", '"'), "", $senha);
        $where = (!$enc)? "`email` = '$login' AND `senha` = '$senha'": "`email` = '$login' AND `senha` = PASSWORD('$senha')";
        $value = $this->db->Read($this->tabela, NULL, $where);

        //se usuario nao existe ou senha nao confere
        if(empty ($value)){
            $this->setErrorMessage("Usuário ou senha incorretos");
            return false;
        }

        //seta a session login
        $value = array_shift($value);
        $var['cod_usuario'] = $value['cod_usuario'];
        $var['email']       = $value['email'];
        cookie::setVar($this->cookie, $var);
        if($value['permissao'] != "Visitante") {
            $this->Redirect(true);
        }
        else $this->Redirect(true);
        return true;
    }//c
    
    //insere um novo usuario
    public function inserir($array){

        $this->user_permission($array);
        
        //dados extras(do sistema)
        if(!isset($array['senha'])){
            $array['senha'] = $this->GeneratePassword(12);
        }
        $senha               = $array['senha'];
        $array['senha']      = 'FUNC_PASSWORD("'.$senha.'")';
        $array['confirmkey'] = $this->GeneratePassword(64);		
        if(!parent::inserir($array)) return false;
        $user = $this->getItem($array['email'], 'email');
        $user['senha'] = $senha;
        
        //responsavel pelas mensagens para o usuario
        $this->LoadModel('usuario/usuario/userDialogs', 'udi');
        $bool = $this->udi->inserir($user);
        $this->setMessages($this->udi->getMessages());
        return $bool;

    }//c

    public function editarDados($id, $dados){
        $var = $this->selecionar(array('cod_usuario'), "`cod_usuario` = '$id' AND `senha` = PASSWORD('".$dados['senha']."')");
        if(empty($var)){
            $this->setErrorMessage("Caro usuário, sua senha está incorreta!");
            return false;
        }
        return $this->editar($id, $dados);
    }//c
    
    public function getAutenticatedUser($cod_usuario, $senha){
        $user = $this->selecionar(array(), "cod_usuario = '$cod_usuario' AND senha = PASSWORD('$senha')");
        if(empty($user)) return $user;
        return array_shift($user);
    }
    
    private function user_permission(&$dados){
        
        //se não existe nenhum webmasters, permite a criação sem considerar as permissões
        $usuario = $this->selecionar(array(), "`permissao` = 'Webmaster'", 1);
        if(empty ($usuario)) return;
        
        //se usuário não é admin a permissão só pode ser de visitante
        if(!$this->UserIsAdmin()) $dados['permissao'] = "Visitante";
        
        //se usuário é admin mas não é webmaster a permissão para visitante
        elseif(!$this->UserIsWebmaster()){
            if($dados['permissao'] == "Webmaster") $dados['permissao'] = "Visitante";
        }
    }

    public function editar($id, $dados, $camp = ""){

        function redirectToIdentidade($dados){
            $_SESSION['guard']['post'] = serialize($dados); 
            $_SESSION['guard']["url"] = CURRENT_PAGE;
            Redirect("usuario/usuario/identidade");
        }
        
        if(!isset($dados['senha'])){
            if(isset($_SESSION['guard'])){
                if(isset($_SESSION['guard']['senha'])) $dados['senha'] = $_SESSION['guard']['senha'];
            }
            if(!isset($dados['senha'])) redirectToIdentidade($dados);
        }
        
        $camp = ($camp == "")?$this->pkey:$camp;
        $user = $this->selecionar(array(), "$camp = '$id' AND senha = PASSWORD('".$dados['senha']."')");
        if(empty($user)){
            $user = $this->getItem($id, $camp);
            if(!empty($user)) redirectToIdentidade($dados);
            else              $this->setErrorMessage("Usuário ou senha incorretos");
            return false;
        }
        
        if(isset($dados['senha_nova'])){
            if($dados['senha_nova'] != $dados['confirmar_senha']){
                $this->setErrorMessage("A senha nova deve ser idêntica à confirmação de senha");
                return false;
            }
        }
        $this->user_permission($dados);
        if(isset($dados['senha'])) unset($dados['senha']);
        if(array_key_exists('senha_nova', $dados)) $dados['senha'] = 'FUNC_PASSWORD("'.$dados['senha_nova'].'")';
        
        if(isset($_SESSION['guard']['senha'])){
            $_POST = unserialize($_SESSION['guard']['post']);
            $_POST['senha'] = $_SESSION['guard']['senha'];
            unset($_SESSION['guard']);
        }
            
        if(!parent::editar($id, $dados, $camp)) return false;
        
        if(isset($_SESSION['guard']['senha']))unset($_SESSION['guard']);
        return true;
    }//c
    
    public function apagar($valor, $chave = "") {
        $usuario = $this->getItem($valor, $chave);
        return parent::apagar($valor, $chave);
    }

    public function Confirm($dados){

        $dados   = explode("-", $dados);
        $usuario = array_shift($dados);
        $chave   = array_shift($dados);
        
        //procura o usuario no banco de dados
        $value = $this->db->Read($this->tabela, NULL, "`cod_usuario` = '$usuario'"); 
        $value = array_shift($value);
        if(empty($value)){
            $this->setErrorMessage("O usuário que você procura não existe");
            return false;
        }

        //a chave de confirmacao esta errada
        if($value['confirmkey'] == ""){
            $this->setSuccessMessage("Usuário confirmado com sucesso!");
            return true;
        }
        
        //a chave de confirmacao esta errada
        if($value['confirmkey'] != $chave){
            $this->setErrorMessage("A chave de confirmação do usuário está incorreta!");
            return false;
        }
        
        $Var['confirmkey'] = "FUNC_NULL";
        if(!parent::editar($value['cod_usuario'], $Var)){
            $this->setErrorMessage("Não foi possível confirmar o usuário");
            return false;
        }
        //$this->Login($value['email'], $value['senha'], false);
        
        //alterou os dados no bd
        $this->setSuccessMessage("Usuário confirmado com sucesso!");
        return true;

    }//c

    public function RecoverPassword($email){

        //procura o usuario no banco de dados
        $value = $this->db->Read($this->tabela, NULL, "`email` = '$email'");
        if(empty($value)){
            $this->setErrorMessage("Este email não está registrado em nossa base de dados");
            return false;
        }

        //edita os dados no banco
        $value = array_shift($value);
        $senha = $Var['confirmkey'] = $this->GeneratePassword(32);
        if(!parent::editar($value['cod_usuario'], $Var)) return false;

        //recupera o corpo e o assunto do email
        $this->LoadModel('usuario/usuario/userDialogs', 'udi');
        $bool = $this->udi->RecoverPassword($value, $senha);
        $this->setMessages($this->udi->getMessages());
        return $bool;
    }

    //confirma a recuperação de senha
    public function ConfirmRecoverPassword($dados){

        $dados   = explode("-", $dados);
        $usuario = array_shift($dados);
        $chave   = array_shift($dados);

        //verifica se existe algum usuario com esta chave de recuperação
        $value = $this->db->Read($this->tabela,NULL, "`cod_usuario` LIKE '$usuario' AND`confirmkey` LIKE '$chave'");
        $value = array_shift($value);
        if(empty ($value)){
            $value = $this->db->Read($this->tabela, NULL, "`cod_usuario` LIKE '$usuario'");
            $value = array_shift($value);
            
            if(empty ($value))  $this->setErrorMessage("Usuário não existe");
            elseif(array_key_exists("key", $value) && $value['key'] != "") $this->setErrorMessage("Chave de confirmação inválida.");
            else{
                $this->setSuccessMessage('Usuário já confirmado');
                return true;
            }
            return false;
        }

        //carrega a senha gerada
        $senha = $this->GeneratePassword(12);
        $Var['senha']      = "FUNC_PASSWORD('".$senha."')";
        $Var['confirmkey'] = "FUNC_NULL";
        if(!$this->db->Update($this->tabela, $Var, "`cod_usuario` = '".$value['cod_usuario'] ."'")){
            $this->setErrorMessage("Não foi possível gerar sua nova senha");
            return false;
        }

        $this->LoadModel('usuario/usuario/userDialogs', 'udi');
        $bool = $this->udi->ConfirmRecoverPassword($value, $senha);
        $this->setMessages($this->udi->getMessages());
        return $bool;

        return true;
    }
    
    public function resend($login){
    	
    	//procura o usuario no banco de dados
        $value = $this->db->Read($this->tabela, NULL, "`cod_usuario` LIKE '$login' || `email` LIKE '$login'"); 
        if(empty($value)){
            $this->setErrorMessage("Usuário inexistente");
            return false;
        }
        $value = array_shift($value);
        
        if($value['confirmkey'] == NULL || $value['key'] == ""){
            $this->setSuccessMessage("Email já confirmado");
            return true;
        }
        
        $Var['confirmkey'] = $value['key'];

        //Se nao conseguiu atualizar tabela
        if(!$this->db->Update($this->tabela, $Var, "`cod_usuario` = '".$value['cod_usuario'] ."'")){
            $this->setErrorMessage("Não foi possível atualizar o banco de dados");
            return false;
        }

        //prepara o email
        $this->LoadResource("html", 'html');
        $url     = $this->html->getLink("usuario/usuario/confirmar/".$value['cod_usuario']."/".$Var['confirmkey']);
        $msg     = "<p><a href='$url'>clique aqui</a> Para completar sua inscrição</p>";
        $assunto = "Reenviar Confirmação";
        $corpo   = $msg;
        
        $this->LoadResource("email", "email");
        $this->email->SendMail($assunto, $corpo, $value['email']);

        $this->setSuccessMessage("Um novo email de confirmação foi enviado para você.");
        return true;
    }
    
    public function needWebmasterLogin(){
        
        //se usuário não está logado ou não é admin
        if(!$this->IsLoged() || !$this->UserIsWebmaster()){
            $this->Logout();
            $this->needLogin();
        }
        
        //se usuário é admin
        else $this->Redirect();
        return true;
    }
    
    public function needAdminLogin(){
        
        //se usuário não está logado ou não é admin
        if(!$this->IsLoged() || !$this->UserIsAdmin()){
            $this->Logout();
            $this->needLogin();
        }
        
        //se usuário é admin
        else $this->Redirect();
        return true;
    }
    
    public function needLogin(){
        if(!$this->IsLoged()){
            $this->LoadResource('html', 'html');
            $url = base64_encode($this->html->getLink(CURRENT_URL));
            if(!isset($_SESSION['refer']))$_SESSION['refer'] = $url;
            Redirect('usuario/usuario', 0, "refer=$url");
        }
        else $this->Redirect();
        return true;
    }
    
    public function Redirect($first_login = false){
        $refer = "";
        if(isset($_GET['refer'])) $refer = $_GET['refer'];
        if(isset($_SESSION['refer'])){
            if($refer == "") $refer = $_SESSION['refer'];
            unset($_SESSION['refer']);
        }

        if($refer == "" && $first_login){
            $this->LoadModel("plugins/plug", "plug");
            try{
                $this->plug->IsAvaible(MODULE_DEFAULT); 
                $refer = base64_encode(URL.MODULE_DEFAULT);
            }
            catch (PageNotFoundException $pne){
                if($this->UserIsAdmin()) $refer = base64_encode(URL.'admin/index.php?url='.MODULE_DEFAULT);
                else $refer = base64_encode(URL.'usuario/index.php?url=usuario/home');
            }
        }
        
        if($refer != ""){
            $refer = base64_decode($refer);
            
            die("<meta http-equiv='Content-Type' content='text/html; charset=utf-8' />
                  <meta http-equiv='refresh' content='0;URL=$refer' />");
        }
        return false;
    }
    
    public function getUserId(){
        $var = cookie::getVar($this->cookie);
        if($var == "") return "";
        
        $cod_usuario = $var['cod_usuario'];
        $item = ($this->getItem($cod_usuario));
        if(!array_key_exists("cod_usuario", $item) || $cod_usuario != $item['cod_usuario']){
            return "";
        }
        return $cod_usuario;
    }

    public function UserIsWebmaster($cod_usuario = ''){
        return $this->UserIsAdmin($cod_usuario, $perm = "Webmaster");
    }
    
    public function UserIsAdmin($cod_usuario = "", $perm = ""){
        $var = cookie::getVar($this->cookie);
        if($var == "") return false;
        
        $cod_usuario = ($cod_usuario == "")?$var['cod_usuario']:$cod_usuario;
        $item = ($this->getItem($cod_usuario));
        if(empty($item)) return false;
        
        if(!array_key_exists("cod_usuario", $item) || $cod_usuario != $item['cod_usuario'])return false;
        if($perm == "") return ($item['permissao'] == "Webmaster" || $item['permissao'] == "Admin");
        else            return ($item['permissao'] == $perm);
    }

    private function GeneratePassword($num = 12){
        $str = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz1234567890';
        $pass = '';
        for($i=0;$i<$num;$i++){
            $pass .= substr($str,rand(0,56),1);
        }
        return $pass;
    }
    
    private function accessDenied(){
        Redirect('usuario', 3, true);
        throw new AcessDeniedException();
    }
    
    public function LoadPerfil($cod){
        if($cod == "") return array();
        $this->LoadModel('usuario/dados'  , 'dobj');
        $this->LoadModel('usuario/usuario', 'uobj');
        $tb1 = $this->dobj->getTable();
        $pk1 = $this->dobj->getPkey();
        
        $tb2 = $this->uobj->getTable();
        $pk2 = $this->uobj->getPkey();
        
        $this->db->Join($tb2, $tb1, array($pk2), array($pk1), "LEFT");
        $item = $this->uobj->getItem($cod);
        //echo $this->db->getSentenca();
        if(empty ($item)) return $item;
        unset($item['newslatter']);
        unset($item['senha']);
        unset($item['permissao']);
        unset($item['confirmkey']);
        return $item;
    }
    
    public function paginate($page, $link = "", $cod_item = "", $campo = "", $qtd = 20, $campos = array(), $adwhere = "", $orderby = "") {
        $this->LoadModel('usuario/dados', 'ud');
        $this->db->Join($this->tabela, $this->ud->getTable(), array('cod_usuario'), array('cod_usuario'), "LEFT");
        $campos = array("$this->tabela.cod_usuario, $this->tabela.email, nome, telefone");
        $var = parent::paginate($page, $link, $cod_item, $campo, $qtd, $campos, $adwhere, $orderby);
        return $var;
    }
    
}

?>
